package FlowGraph;

import java.util.Iterator;
import FlowGraph.*;

public class AssemFlowGraph extends FlowGraph {
	java.util.Dictionary ht;

	public Assem.Instr instr(Graph.Node n) {
		return (Assem.Instr) ht.get(n);
	}

	public Temp.TempList def(Graph.Node node) {
		return instr(node).def();
	}

	public Temp.TempList use(Graph.Node node) {
		return instr(node).use();
	}

	public boolean isMove(Graph.Node node) {
		return instr(node) instanceof Assem.MOVE;
	}

	public AssemFlowGraph(Assem.InstrList instrs) {
		ht = new java.util.Hashtable();
		java.util.Dictionary l2n = new java.util.Hashtable();

		// Add all instructions as nodes
		for (Assem.InstrList p = instrs; p != null; p = p.tail) {
			Graph.Node n = new Graph.Node(this);
			ht.put(n, p.head);
			if (p.head instanceof Assem.LABEL)
				l2n.put(((Assem.LABEL) p.head).label, n);
		}
		// Add edges from each branch instruction node to target node(s)
		for (Graph.NodeList p = nodes(); p != null; p = p.tail) {
			Graph.Node n = p.head;
			Assem.Targets jumps = (Assem.Targets) instr(n).jumps();
			if (jumps == null && p.tail != null) {
				addEdge(n, p.tail.head); // Fall through with edge to next
				// instruction
			} else if (jumps != null) { // Jumps - Edge to target label node
				Temp.LabelList l = jumps.labels;
				while (l != null) {
					addEdge(n, (Graph.Node) l2n.get(l.head));
					l = l.tail;
				}
			}
		}
	}
}